DeckSurf Now Supports All Stream Deck Devices
Table of Contents
DeckSurf, my open-source SDK that covers the reverse-engineered protocol for interacting with Stream Deck devices, is now more-or-less complete in terms of devices it can identity and run against. Starting with the latest 0.0.6
release (you can get it on NuGet), I’ve introduced support for the following Stream Deck models: Neo, Mini, Original, and MK.2. XL and Plus were already supported, as I documented in my previous blog posts.
The need for full Stream Deck support #
This came on the heels of a few community requests that came my way in the past year. And while I started the project solely because I had a Stream Deck XL that I wanted to control outside the boundaries of the stock software, it quickly grew into something a bit more generic. So, as an open source project maintainer, I set out a goal to make sure that in the new year (this year, that is) I add support for other Stream Deck devices as well. Which led me to kick off the new year by redeeming my yearly Microsoft perks (all full-time employees get a fixed allowance every year) on January 1st on some of these devices.

This gave me the opportunity to then sit down and dissect the ins and outs of the USB protocol of each of these devices. January proved to be a bit of a hectic month, but in late February I got a chance to write everything up and productize it.
Some lessons learned #
For the most part, and as trite as it sounds - you can peek at the source code to see what I did. I was pleasantly surprised that for the most part my code worked fine across different Stream Deck models.
The one exception was the Stream Deck Mini, where I needed to convert the images for the buttons to Bitmap (BMP) format before sending them to each of the keys on the device. That same Stream Deck Mini is also significantly more basic when it comes to what gets packaged inside the packets sent to the device. It effectively got rid of most of the in-packet things that existed for other device variants - things like declaring the length of the message within it. It also has a slightly different way of setting the brightness by using a 17-byte packet instead of the traditional 32-byte one. I can only assume that because it’s a significantly smaller device they had to reduce the compute capabilities, meaning that they started relying on a simplified protocol implementation.
For the Stream Deck Neo, the screen is also significantly simplified compared to that of a Stream Deck Plus. While the latter had a 800px x 100px touch screen, the Neo has a 248px x 50px static information bar (not touch at all), surrounded by two touch surfaces that are, for all intents and purposes, just another button. The bar supports setting any JPEG image that is resized properly - it really wasn’t shocking to see that even the dynamic data fed from the Stream Deck’s official client is nothing other than a self-generated JPEG:

I mentioned that there are buttons that surround the screen - they are just like other buttons in terms of interaction, but have no display section associated with them, meaning that at most you can set the LED color behind them. You can set separate colors to those touch surfaces - something that the stock software doesn’t allow you to do (they only allow pre-cooked colors for specific information bar themes), but which can be done with DeckSurf as easily as:
var devices = DeviceManager.GetDeviceList();
var device = ((List<ConnectedDevice>)devices)[0];
device.SetKeyColor(8, Color.Red);
device.SetKeyColor(9, Color.Green);

Oh yeah, and another neat thing that DeckSurf can do for your Neo - you can set the screen to show any image, not just the system time that the Stream Deck software allows you to. Really, this is why I built this project, to give me freedom to control my hardware the way I want to.
What’s next #
The next step is making sure that I battle-test this SDK. I need to update the DeckSurf CLI to use the new version of the SDK and see what the SDK ergonomics are like, since this is the default “baseline” project that will utilize every single nook and cranny of the DeckSurf library. I give myself just enough room to go and fix APIs, even if that means breaking them, up until the point the library hits 1.0.0
, after which breaking changes will only be possible on every major version revision.
After all, what I thought is a good API might not be once I start actually using it.

I take Adam Savage’s stance that “failure is always an option” to heart (not that it’s applicable to everything), because what I started with is not necessarily the best design, or even the best implementation of the design I had in mind, so I want to make sure that I spend some time refining it before putting a seal of 1.0.0
approval. Here be a lot of dragons if you take a dependency on the library in its current state.
Feedback #
I would love to get your thoughts and feedback on the project! You can always get started on the website, where I maintain all the documentation and pointers, or go to GitHub and open an issue there. This project became more than just my own hobby thing - it’s something that I am building for myself and the community, so your input here would be extremely welcome.